Skip to main content

Web SDK

Add AR Clip VPS to your own web page. The Web SDK finds where the visitor stands on your VPS maps right in the browser, with no app to install.

Before you start​

  • An API key. Write to us through Support to get one.
  • Location IDs of your maps. Every map has one — see Introduction.
  • A page served over HTTPS. Browsers give the camera and motion sensors only to secure pages; localhost counts as secure.

Install​

npm install @web-ar-studio/webar-engine-sdk

The package is on npm and comes with TypeScript types.

Start VPS​

VPS runs inside a world tracking session. Add vps to init() and list your location IDs. The SDK draws nothing itself, so render the scene with any engine: three.js, Babylon.js, PlayCanvas or plain WebGL.

import * as THREE from "three";
import WAS, {
PROJECT_MODE_SLAM,
TRIGGER_MODE_SLAM,
CAMERA_MODE_ENVIRONMENT,
PROVIDER_8THWALL,
EVENT_FRAME,
EVENT_VPS_READY,
EVENT_VPS_LOCALIZED,
EVENT_VPS_NOT_LOCALIZED,
EVENT_VPS_ERROR,
} from "@web-ar-studio/webar-engine-sdk";

const was = new WAS();

const { canvas, context } = await was.init({
apiKey: "your-api-key",
mode: PROJECT_MODE_SLAM,
cameraMode: CAMERA_MODE_ENVIRONMENT,
container: document.querySelector("#ar"),
triggers: [{ id: 1, mode: TRIGGER_MODE_SLAM, source: null }],
vps: { locationIds: ["your-location-id"] },
});

const renderer = new THREE.WebGLRenderer({ canvas, context });

was.on(EVENT_VPS_READY, () => console.log("VPS started"));
was.on(EVENT_VPS_LOCALIZED, ({ locationId, offset }) => {
console.log("Found the place on map", locationId, offset);
});
was.on(EVENT_VPS_NOT_LOCALIZED, ({ status, statusDescription }) => {
console.log("Not found yet:", status, statusDescription);
});
was.on(EVENT_VPS_ERROR, (message) => console.warn("VPS error:", message));

// Tracking and VPS start with the frame callback. Register it from a tap:
// WebXR and iPhone motion sensors need a user gesture.
startButton.onclick = () =>
was.on(EVENT_FRAME, () => renderer.render(scene, camera));

Leave out locationIds to localize globally, without naming a map. It takes longer, so raise requestTimeoutMs.

Pass vps to init()

In Chrome on Android, camera access for VPS is granted only when the session starts. If you start without vps, you cannot turn VPS on later in that session: setupVPS() throws VpsError.

Where it works​

The SDK picks a tracking engine (provider) on the device. With the default "auto" it tries webxr first, then 8thwall.

EngineWhereVPS
webxrChrome on AndroidYes. The SDK moves the scene onto the map itself.
8thwallBrowsers without WebXR, such as Safari on iPhoneYes. You apply offset yourself.
arclip-webarOnly when you ask for itNo

Place content on the map​

Place your content in map coordinates, the coordinates of your VPS map. When VPS finds the place, EVENT_VPS_LOCALIZED gives offset: the move from the tracking world onto the map.

  • On webxr the SDK has already applied offset and eases it in, so map content appears in place.
  • On 8thwall the SDK only reports offset. Put map content in one group and give the group the inverse of offset on every fix:
const mapRoot = new THREE.Group(); // everything placed in map coordinates
scene.add(mapRoot);

was.on(EVENT_VPS_LOCALIZED, ({ offset }) => {
if (was.getActiveProviderId() !== PROVIDER_8THWALL) return; // webxr applies it itself
const { position: p, orientation: q } = offset;
new THREE.Matrix4()
.compose(
new THREE.Vector3(p.x, p.y, p.z),
new THREE.Quaternion(q.x, q.y, q.z, q.w),
new THREE.Vector3(1, 1, 1),
)
.invert()
.decompose(mapRoot.position, mapRoot.quaternion, mapRoot.scale);
});

The SDK accepts a fix only when the match is strong enough and the jump from the last fix is one a person could walk. Everything else arrives as EVENT_VPS_NOT_LOCALIZED. This keeps content from jumping in places that look alike, such as long corridors.

Events​

EventWhat you get
EVENT_VPS_READYNothing. VPS has started.
EVENT_VPS_LOCALIZEDlocationId, offset (position, orientation), trackingPosition, trackingRotation, vpsPosition, vpsRotation, timestamp
EVENT_VPS_NOT_LOCALIZEDstatus, statusDescription, failCount
EVENT_VPS_ERRORAn error message, as a string

Control VPS​

MethodWhat it does
startVPS(), stopVPS()Resume or pause localization
isVPSActive()Tells whether VPS is running
setVPSLocationIds(ids)Switch to other maps; an empty list localizes globally
setupVPS(config)Change VPS settings during a session
updateVPSSession()Start a new VPS session, so earlier fixes no longer affect new ones
resetTracking()Drop the VPS correction and start over, for example after a wrong fix

Settings​

Every field of vps is optional. The SDK takes apiKey from init(), so you do not repeat it.

FieldDefaultWhat it does
locationIdsnoneMaps to compare the camera image with. Without it, VPS localizes globally.
captureInterval2500Time between localization requests, in ms
requestTimeoutMs20000How long to wait for an answer, in ms
maxFailsCount5Misses in a row before the SDK starts a new VPS session
imageFormat"jpeg""jpeg" or "webp". Use WebP only with a server that reads it. Where the browser cannot encode WebP, the SDK sends JPEG.
jpegQuality1Image quality, from 0 to 1
targetWidth, targetHeight540, 960Size of the frame sent to the server
minInlierRatio, minNumInliers0.6, 600How strong a match must be to count
maxJumpBaseMeters, maxJumpSpeedMps3, 2How far a new fix may move from the last one: maxJumpBaseMeters plus maxJumpSpeedMps for every second since the last fix
serverUrlAR Clip VPSAnother VPS server
sendApiKeyHeadertrueSends the key in the x-vps-apikey header. Turn it off only for your own server that cannot accept this header.

Errors​

If VPS cannot run in this session, init() or a VPS method fails with an error named VpsError (constant VPS_ERROR). Errors after the start, such as a failed request, arrive in EVENT_VPS_ERROR.

More​

  • The package README covers the other tracking modes, anchors and the full three.js setup.
  • To set up VPS without code, use VPS scenes in AR Clip Studio.

Next: Supported devices — phones, browsers and headsets.